import {CONSTANTS} from '../common/consts.js';
import {Tool} from '../common/tool.js';
import {Terminals} from '../lexer/terminal.js';
import {NonTerminals} from '../lexer/nonTerminal.js';

/**
 * represents a production rule in a formal grammar.
 * this function defines the transformation from a non-terminal symbol
 * to a sequence of terminal and/or non-terminal symbols, forming the structure
 * of the language defined by the grammar.
 * huizi 2024
 */
function production(grammar, productionStr){
    const symbols = [];
    //build symbol chain
    productionStr.trim().split(/\s+/).forEach(word=>{
        const symbol = Terminals.valueOf(word);
        if(symbol ===undefined){
            symbol = NonTerminals.valueOf(word);
            if(nonTerminal===undefined){
                Tool.grammarErr(`terminal or non terminal ${word} is not found in outline grammar`);
            }
        }
        symbols.push(symbol);
    })

    //check left recursion
    if(!symbols[0].isTerminal() && symbols[0].name()===grammar.name()){
        Tool.grammar(`left recursion on ${grammar.name()}`);
    }

    return {
        display: ()=> `${grammar.name()}${CONSTANTS.MINUS_ARROW}${productionStr}`,
        grammar: ()=>grammar,
        isEmpty: ()=>symbols.size()==1 && symbols[0]==Terminal.EPSILON
    }
}